module Switches(clk, lock, abus, dbus, we, in);
	parameter NUM;
	parameter ADDRDATA;
	parameter ADDRCTRL;
	parameter CLOCKS_IN_10MS;
	input clk, lock;
	input [31:0] abus;
	inout [31:0] dbus;
	input we;
	input [(NUM-1):0] in;
	
	parameter BITREADY = 0;
	parameter BITOVRRN = 2;
	parameter BITIE    = 8;
	
	reg [7:0] ctrl;
	reg [31:0] count;
	reg [(NUM-1):0] data,data_last,hold_data;
	reg holding;

	wire selCtl=(abus == ADDRCTRL);
	wire selData=(abus == ADDRDATA);
	wire wrCtl=we&&selCtl;
	wire rdCtl=(!we)&&selCtl;
	wire rdData=(!we)&&selData;
	wire change=(in != data);

	wire reset = !lock;

	always @(posedge clk or posedge reset) begin
		if (reset) begin
			holding <= 1'b0;
			data_last <= data;
			data <= {NUM{1'b0}};
			ctrl <= {NUM{1'b0}};
			count <= 32'b0;
		end
		else begin
			// bus interface
			if (wrCtl) begin
				if (!dbus[BITOVRRN])
					ctrl[BITOVRRN] <= 1'b0;
			end
			else if (rdData) begin
				ctrl[BITREADY] <= 1'b0;
			end
			
			// debounce
			if (!holding && change) begin
				holding <= 1'b1;
				hold_data <= in;
				count <= 32'b0;
			end
			if (holding) begin
				count <= count + 1;
				// stop holding if value unstable
				if (in != hold_data)
					holding <= 1'b0;
				if (count == (CLOCKS_IN_10MS-1)) begin
					holding <= 1'b0;
					data <= hold_data;
				end
			end

			data_last <= data;
			// this comparison *might* be a cycle behind in setting ready/overrun
			if (data_last != data) begin
				ctrl[BITREADY] <= 1'b1;
				if (ctrl[BITREADY])
					ctrl[BITOVRRN] <= 1'b1;
			end
		end
	end

	assign dbus = rdCtl ? {24'b0,ctrl} :
						rdData ? data :
						32'hZZZZZZZZ;

endmodule
